package controller

import (
	"gitee.com/huangxinbo/xcas/internal/app/base"
	"gitee.com/huangxinbo/xcas/internal/service"
	"gitee.com/huangxinbo/xcas/pkg/response"
	"github.com/gin-gonic/gin"
)

type FileController struct {
	base    *base.Base
	service *service.Service
}

func NewFileController(base *base.Base, service *service.Service) *FileController {
	return &FileController{
		base:    base,
		service: service,
	}
}

func (c *FileController) RegisterRoutes(router *gin.Engine) {
	uploadGroup := router.Group("/api/file")
	{
		uploadGroup.POST("/upload", c.UploadFile)
		uploadGroup.GET("/image/:id", c.GetImage)
	}
}

// UploadFile handles file upload
//
//	@Summary		Upload file
//	@Description	Upload a file to the server
//	@Tags			file
//	@Accept			multipart/form-data
//	@Produce		json
//	@Param			file	formData	file	true	"File to upload"
//	@Security		BearerAuth
//	@Success		200	{object}	model.FileResponseData
//	@Router			/api/file/upload [post]
func (c *FileController) UploadFile(ctx *gin.Context) {
	// Get the file from the form
	fileHeader, err := ctx.FormFile("file")
	if err != nil {
		response.Error[any](ctx, response.INVALID_PARAMS, c.base.I18n.T("File is required"), nil)
		return
	}

	// Validate file size from config
	maxSize := int64(c.base.Config.Upload.MaxSize) << 20 // Convert MB to bytes
	if fileHeader.Size > maxSize {
		response.Error[any](ctx, response.INVALID_PARAMS, c.base.I18n.T("File is too large"), nil)
		return
	}

	// Upload file using service
	fileRecord, err := c.service.FileService.UploadFile(ctx, fileHeader)
	if err != nil {
		c.base.Logger.Error("Failed to upload file: " + err.Error())
		response.Error[any](ctx, response.ERROR, c.base.I18n.T("Failed to upload file"), nil)
		return
	}

	// Return success response
	response.Success[any](ctx, c.base.I18n.T("Success"), map[string]interface{}{
		"id": fileRecord.ID,
	})
}

// GetFileContent retrieves file content by ID
//
//	@Summary		Get file content
//	@Description	Get file content by ID
//	@Tags			file
//	@Produce		octet-stream
//	@Param			id	path		string	true	"File ID"
//	@Success		200	{string}	binary
//	@Security		BearerAuth
//	@Router			/api/file/image/{id} [get]
func (c *FileController) GetImage(ctx *gin.Context) {
	id := ctx.Param("id")
	if id == "" {
		response.Error[any](ctx, response.INVALID_PARAMS, c.base.I18n.T("File ID is required"), nil)
		return
	}

	content, contentType, err := c.service.FileService.GetFileContent(ctx, id)
	if err != nil {
		c.base.Logger.Error("Failed to get file content: " + err.Error())
		response.Error[any](ctx, response.ERROR, c.base.I18n.T("Failed to get file content"), nil)
		return
	}

	// Set appropriate headers for file download/display
	ctx.Header("Content-Type", contentType)
	ctx.Header("Content-Disposition", "inline")
	ctx.Header("Cache-Control", "public, max-age=3600") // Cache for 1 hour

	// Write file content to response
	ctx.Data(200, contentType, content)
}
